/**
 * create by young (young2f@outlook.com) on 2023/4/16
 */
'use strict';
const base = require('../base/serviceBase');
const _ = require('lodash');
const _stringUtils = require('../utils/stringUtils');
const table = 'OutboundOrder';
const moment = require('moment');
module.exports = class extends base {
  /**
   * 创建出货单
   * @param body
   * @returns {Promise<{result: *, status: string}>}
   */
  async createOutboundOrder(body) {
    const { ctx } = this;
    const { orderCode, tenantCode } = body;
    const salesOrder = await ctx.app.dbs.findOne(table, { orderCode, tenantCode });
    if (salesOrder) {
      throw new Error('出货单已创建');
    }
    //  console.log('create outboundOrder', body);
    body.code = _stringUtils.getCode('OUT');


    const result = await ctx.app.dbs.insert(table, body);
    return { status: 'ok', result };
  }

  async findMany(body) {
    const { ctx } = this;
    const { start, end, key, vendor, code } = body;
    console.log('find outbound', body);
    const _key = key ? key : 'createdTs';
    if (start && end) {
      body[_key] = {
        $gte: new Date(moment(start)
          .valueOf()),
        $lt: new Date(moment(end)
          .valueOf())
      };
    }
    delete body['start'];
    delete body['end'];
    const sort = {};
    sort[_key] = -1;
    if (vendor) body['vendor'] = { $regex: vendor };
    if (code) body['code'] = { $regex: code };
    const res = await ctx.app.dbs.aggregate(table, [
      { $match: { ...body } },
      { $sort: { ...sort } },
    ]);
    const result = [];
    _.map(res, item => {
      const { labels } = item;
      _.map(labels, it => {
        _.assign(item, it);
      });
      result.push(item);
    });
    return { status: 'ok', result };
  }

  async findOne(body) {
    const { ctx } = this;
    const result = await ctx.app.dbs.findOne(table, body);
    return { status: 'ok', result };
  }

  async updateOne(body) {
    const { tenantCode, code } = body;
    const { ctx } = this;
    const result = await ctx.app.dbs.updateOne(table, { tenantCode, code }, body);
    return { status: 'ok', result };
  }

  async deleteOne(body) {
    const { tenantCode, orderCode } = body;
    const { ctx } = this;
    const result = await ctx.app.dbs.deleteOne(table, { tenantCode, orderCode });
    return { status: 'ok', result };
  }

  /**
   * 创建出货记录
   * @param body
   * @returns {Promise<{result: *, status: string}>}
   */
  async createOutboundLot(body) {
    const { ctx, service } = this;
    const {
      tenantCode,
      orderCode,
      tenantName,
      createUser,
      createUsername, shippingFee = 0,
      createdTs, materials,
      _code,
      prodName,
      lotCode = 'OUT' + Date()
        .valueOf()
    } = body;
    console.log('createOutboundLot body', body);

    body.code = _code;
    const { deliverChannel } = body;
    const order = await ctx.app.dbs.findOne('SalesOrder', { tenantCode, code: orderCode });
    /**
     * 原料的出货批次
     */
    const { customer, customerCode, } = order;

    /**
     * 创建商品的出货记录
     */
    const result = await ctx.app.dbs.insert('OutboundLot', { ...body, customer, customerCode });
    /**
     * 扣库存
     */

    _.map(materials, async material => {
      const { materialContent, code } = material;
      const incStoreCount = (body.outboundCount / 100) * materialContent;
      const res2 = await ctx.app.dbs.updateOne('Material', {
        code,
        tenantCode
      }, { $inc: { storeCount: -incStoreCount } });
    });

    /**
     * 更新订单商品的出货数量和金额
     */


    const { outboundCount = 0, outboundAmount = 0 } = order;
    const _count = parseFloat(outboundCount) + parseFloat(body.outboundCount);
    const _amount = parseFloat(outboundAmount) + parseFloat(body.outboundCount) * parseFloat(body.price);
    const outboundDate = moment(body.outboundDate)
      .format('YYYY-MM-DD hh:mm:ss');

    const updateCount = await ctx.app.dbs.updateOne('SalesOrder', {
      tenantCode,
      code: orderCode
    }, { outboundCount: _count, outboundDate, outboundAmount: _amount });

    /**
     * 更新采购物料批次
     */
    _.map(materials, async material => {
      const { materialCount, pmLotId } = material;
      const resultPML = await ctx.app.dbs.updateOne('ProcureMaterialRecord', { pmLotId }, {
        $inc: { outboundCount: materialCount },
        outboundDate
      });
    });

    if (deliverChannel) {
      const result = await ctx.app.dbs.insert('ShippingFee', {
        code: 'SPF' + Date.now()
          .valueOf(),
        deliverChannel,
        tenantCode,
        shippingFee,
        orderCode, name: prodName, prodCode: _code, lotCode, count: body.outboundCount
      });
    }
    /**
     * 保存历史操作记录
     * @type {{table: string, name: string, oldData, tenantCode, code, tenantName, createUser, createUsername, createdTs}}
     */
    const history = {
      table: 'SalesOrder',
      name: '订单创建出货记录',
      oldData: body,
      tenantCode,
      code: orderCode,
      tenantName,
      createUser,
      createUsername,
      createdTs
    };
    const historyRes = await ctx.app.dbs.insert('History', history);
    return { status: 'ok', result };
  }

  /**
   * 查询出货记录
   * @param body
   * @returns {Promise<{result: *, status: string}>}
   */
  async findOutboundLots(body) {
    const { ctx } = this;
    const result = await ctx.app.dbs.find('OutboundLot', body);
    return { status: 'ok', result };
  }

  /**
   * 删除出货记录
   * @param body
   * @returns {Promise<{result: *, status: string}>}
   */
  async deleteOutboundLot(body) {
    const { ctx } = this;
    const {
      lotCode,
      code, materials,
      tenantCode,
      outboundCount, price,
      orderCode,
      tenantName,
      createUser,
      createUsername,
      createdTs
    } = body;
    console.log('deleteOutboundLot body', body);
    const result = await ctx.app.dbs.deleteOne('OutboundLot', { lotCode, tenantCode });
    const result1 = await ctx.app.dbs.deleteOne('ShippingFee', { lotCode, tenantCode });
    const order = await ctx.app.dbs.findOne('SalesOrder', { tenantCode, code: orderCode });

    const count = parseFloat(order.outboundCount) - parseFloat(outboundCount);
    const amount = parseFloat(order.outboundAmount) - parseFloat(outboundCount * price);

    const res = await ctx.app.dbs.updateOne('SalesOrder', { tenantCode, code: orderCode }, {
      outboundCount: count.toFixed(2), outboundAmount: amount.toFixed(2),
    });


    _.map(materials, async material => {
      const { materialCount, pmLotId, materialContent, code } = material;
      /**
       * 还原库存
       */
      const incStoreCount = (body.outboundCount / 100) * materialContent;
      const res2 = await ctx.app.dbs.updateOne('Material', {
        code,
        tenantCode
      }, { $inc: { storeCount: incStoreCount } });

      const resultPML = await ctx.app.dbs.updateOne('ProcureMaterialRecord', { pmLotId }, {
        $inc: { outboundCount: -materialCount },
      });
    });
    const history = {
      table: 'SalesOrder',
      name: '订单删除出货记录',
      oldData: body,
      tenantCode,
      code: orderCode,
      tenantName,
      createUser,
      createUsername,
      createdTs
    };
    const historyRes = await ctx.app.dbs.insert('History', history);
    return { status: 'ok' };
  }


  async findShippingFeeMany(body) {
    const { ctx } = this;
    console.log('find shippingFeeMany', body);
    const { deliverChannel } = body;
    if (deliverChannel) {
      body.deliverChannel = { $regex: deliverChannel };
    }
    const list = await ctx.app.dbs.find('ShippingFee', body);
    let fee = 0,
      _count = 0,
      payment = 0;
    _.map(list, item => {
      const { shippingFee = 0, count = 0, paymentAmount = 0 } = item;
      fee += shippingFee;
      _count += count;
      payment += paymentAmount;
    });
    return { status: 'ok', result: { list, fee, count: _count, payment } };
  }

  async updateShippingFee(body) {
    const { ctx } = this;
    const { code, tenantCode, shippingFee } = body;
    const result = await ctx.app.dbs.updateOne('OutboundLot', { code, tenantCode }, { shippingFee });
    const result1 = await ctx.app.dbs.updateOne('ShippingFee', { code, tenantCode }, body);
    return { status: 'ok', result };
  }

  async createShippingFee(body) {
    const { ctx } = this;
    console.log('updateShippingFeeMany createShippingFee', body);
    const {
      code = 'SPF' + Date.now()
        .valueOf()
    } = body;
    const result = await ctx.app.dbs.insert('ShippingFee', body);
    return { status: 'ok', result };
  }

  async deleteShippingFee(body) {
    const { ctx } = this;
    console.log('deleteShippingFee shippingFeeMany', body);
    const { tenantCode, code } = body;
    const result = await ctx.app.dbs.deleteOne('ShippingFee', { code, tenantCode });
    return { status: 'ok', result };
  }

  async procureReturnOfGoodsOutbound(body) {
    const { ctx } = this;
    const { orderCode, tenantCode, code, outboundCount, outboundDate } = body;
    const result = await ctx.app.dbs.updateOne('ProcureMaterialReturnOrder', {
      orderCode,
      tenantCode
    }, body);

    /**
     * 扣库存
     */
    const res2 = await ctx.app.dbs.updateOne('Material', {
      code,
      tenantCode
    }, { $inc: { storeCount: -outboundCount } });
    /**
     * 创建出库批次记录
     */
    body.lotType= '采购物料退货出库';
    body.lotCode=  'OLT' + moment()
      .format('YYYYMMDDHHmmss');

   const res1 = await ctx.app.dbs.insert('OutboundLot', body);

    return { status: 'ok', result };
  }
};
